import Taro from '@tarojs/taro';
import { ACCESS_TOKEN_KEY } from '../config';

const request = (options: REQUEST.RequestParams) => {
  Taro.hideLoading();
  const {
    url,
    method,
    data,
    header,
    loading = false,
    loadingTitle,
    openErrTips = true,
    contentType,
    useToken = true,
    mask = true,
    errTipsContent,
    openCodeErrTips = true,
    timeout = 60000,
    enableHttp2 = true,
    enableQuic = true,
    enableCache = true,
    openCodeSuccessTips = false,
  } = options;
  /** 过滤扩展属性 */
  const requestParams: REQUEST.RequestParams | any = {
    url,
    method,
    data,
    header: {
      'content-type': contentType || 'application/json',
      authorization: Taro.getStorageSync(ACCESS_TOKEN_KEY) ?? '',
      ...header,
    },
    /** 请求是否带 loading， 传递到 请求响应拦截器 清除 loading */
    loading,
    openErrTips,
    timeout,
    enableHttp2,
    enableQuic,
    enableCache,
  };
  if (useToken === false) {
    delete requestParams.header[ACCESS_TOKEN_KEY];
  }
  /** 检测是否开启loading层 是否打开mask */
  if (loading) {
    Taro.showLoading({
      title: loadingTitle || '加载中...',
      mask: mask === false ? false : true,
    });
  }
  return new Promise<any>((resolve, reject) => {
    Taro.request(requestParams)
      .then((res) => {
        let errorMessage = '';
        switch (res.statusCode) {
          case 400:
            errorMessage = '请求错误(400)';
            break;
          case 401:
            errorMessage = '未授权，请重新登录(401)';
            break;
          case 403:
            errorMessage = '拒绝访问(403)';
            break;
          case 404:
            errorMessage = '请求出错(404)';
            break;
          case 408:
            errorMessage = '请求超时(408)';
            break;
          case 500:
            errorMessage = '服务器错误(500)';
            break;
          case 501:
            errorMessage = '服务未实现(501)';
            break;
          case 502:
            errorMessage = '网络错误(502)';
            break;
          case 503:
            errorMessage = '服务不可用(503)';
            break;
          case 504:
            errorMessage = '网络超时(504)';
            break;
          case 505:
            errorMessage = 'HTTP版本不受支持(505)';
            break;
        }
        const successStatusCode = [200];
        /** 大多数请求中 success并不代表成功，需要我们自己检测statusCode来确保 */
        if (successStatusCode.includes(res.statusCode)) {
          switch (res.data?.code) {
            case 401:
              Taro.setStorageSync(ACCESS_TOKEN_KEY, '');
              Taro.navigateTo({ url: '/subpages/login/login' });
              break;
            case 200:
              if (openCodeSuccessTips) {
                setTimeout(() => {
                  Taro.showToast({
                    icon: 'none',
                    title: res.data?.msg ?? '',
                    duration: 2000,
                  });
                }, 300);
              } else {
                loading && Taro.hideLoading();
              }
              break;
            default:
              if (openCodeErrTips) {
                setTimeout(() => {
                  Taro.showToast({
                    icon: 'none',
                    title: res.data?.msg ?? '',
                    duration: 2000,
                  });
                }, 300);
              }
              break;
          }
          /** 成功 */
          resolve(res.data);
        } else {
          /** 如果失败 检测是否直接提示信息 */
          if (openErrTips) {
            setTimeout(() => {
              Taro.showToast({
                icon: 'none',
                title: errTipsContent ?? errorMessage ?? '网络不好，请求失败！',
                duration: 2000,
              });
            }, 300);
          }
          /** 失败 */
          reject(res);
        }
      })
      .catch((err) => {
        if (openErrTips) {
          Taro.showToast({
            icon: 'none',
            title: errTipsContent ?? '网络不好，请求失败！',
            duration: 3000,
          });
        }
        reject(err);
      });
  });
};

export default request;
